/*  This file is part of the comicconquer project
    Copyright (C) 2010 Reach <reach334@gmail.com>

    ComicConquer is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This software is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public 
    License along with this software.  If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef MOUSECONTROL_H 
#define MOUSECONTROL_H

#include "mist.h"
#include <QtGui/QtGui>

#define DRAG_THRESH 30  // threshold use to judge a drag action

// the event to describe the gesture send by MouseControler
struct GestureEvent
{
    int gesture;
    QPoint clickPos;
    QPoint offset; // frome click position to release position
};

// represent the drag directions as drag actions of gesture
enum DragType
{
    DragNone,
    DragClick,
    DragUp,
    DragDown,
    DragLeft,
    DragRight,
};

// add a drag action to end of gesture
#define ADD_DRAG_ACT(gesture, AddEvent) do{\
(gesture) = ((gesture)<<3) | (AddEvent);\
}\
while(0)

// delete the last drag action  of gesture
#define DEL_DRAG_ACT(gesture) do{\
(gesture)>>=3;\
}\
while(0)

// receive the last drag acton of gesture
#define LAST_DRAG_ACT(gesture) ((gesture)&7)

// the macro need to add to the QObject declaration which use MouseControler
#define CO_MOUSECONTROL \
private: \
MouseControl m_mouseControl; \
private slots: \
void mousePressEvent(QMouseEvent* event) \
{ \
    m_mouseControl.mousePressEvent(event); \
} \
void mouseMoveEvent(QMouseEvent* event) \
{ \
    m_mouseControl.mouseMoveEvent(event); \
} \
void mouseReleaseEvent(QMouseEvent* event) \
{ \
    m_mouseControl.mouseReleaseEvent(event); \
}

// the macro attatch QObject and MouseControler
#define CO_MOUSEATTATCH \
m_mouseControl.attatchWidget(this)

class MouseControl : QObject
{
    Q_OBJECT

    //-- constructor
public:
    MouseControl(QObject* parent = 0);

    //-- public methods
public:
    void attatchWidget(QWidget* widget);
    void mousePressEvent(QMouseEvent* event);
    void mouseMoveEvent(QMouseEvent* event);
    void mouseReleaseEvent(QMouseEvent* event);

    //-- signals
    signals:
    void sendGestureEvent(GestureEvent* event);

    //-- private slots
private slots:
    void emitEevent();

    //-- private members
private:
    int m_gesture;
    DragType m_dragState;
    DragType m_dragStateLast;
    int m_dragCount;
    QPoint m_startPos;
    QPoint m_lastPos;
    QPoint m_releasePos;
    GestureEvent m_gestureEvent;

    QTimer m_timer;
};

#endif  // MOUSECONTROL_H
